package eventservice.impl;

import java.rmi.RemoteException;
import java.rmi.server.Unreferenced;

import eventservice.Event;
import eventservice.RemotelyPushable;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

public class PushConsumerProxyImpl extends Thread
		implements RemotelyPushable, Unreferenced {

	private static final long serialVersionUID = 1L;
	private final RemotelyPushable consumer;
	private final ArrayList<Event> events;
	private boolean registered;
	private int buffersize;

	PushConsumerProxyImpl(RemotelyPushable consumer, int buffersize)
			throws RemoteException {
		super();
		this.consumer = consumer;
		registered = true;
		events = new ArrayList<Event>();
		this.buffersize = buffersize;
	}

	// Ezt az EventChannelImpl hivja.
	// Ha uj esemeny erkezik, felebreszti a szalat
	public void push(Event event) throws RemoteException {
		synchronized (events) {
			if (events.size() >= buffersize) {
				events.remove(0);
			}
			events.add(event);
			System.err.println("Debug: PushConsumerProxyImpl added a new Event");
			events.notify();
		}
	}

	// Ez az onallo szal kodja.
	// Végtelen ciklusban fut, amíg a registered értékefalse-ra nem változik.
	// A ciklusban: ha nincs a pufferben esemény, addig var,
	// amig fel nem ebresztik. Ha felébredt, vagy volt esemény,
	// akkor az ujonnan jott esemeny(eke)t atkuldi a consumer-nek push-sal,
	// majd a ciklus kezdõdik elölrõl
	// Figyeljünk a kölcsönös kizárásra!
	public void run() {
		while (registered) {
			try {
				synchronized (events) {
					while (events.isEmpty()) {
						events.wait();
					}
					Event e = (Event) events.remove(0);
					try {
						consumer.push(e);
					} catch (RemoteException ex) {
						Logger.getLogger(PushConsumerProxyImpl.class.getName()).log(Level.SEVERE, null, ex);
					}

				}
			} catch (InterruptedException ie) {
				// Már nincs regelve, felébredtünk.
			}
		}
	}

	// itt jelezzuk a szalnak, hogy vege a futasnak
	public void unreferenced() {
		registered = false;
		this.interrupt();
	}
}
